package com.t3.animation
{
	import com.t3.events.AnimationEvent;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.TimerEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.Timer;
	
	import gs.TweenMax;

	/**
	 * HighlightAnimation klasse
	 * Deze klasse regelt de animatie van de highlights. 
	 * @author David Hoevers
	 */
	
	public class HighlightAnimation extends Sprite
	{
		protected var _bmp:Bitmap;
		protected var _bmpHighlight:Bitmap;
		protected var _index:uint = 0;
		protected var _highlightMask:Shape;		
		protected var _highlights:Array;
		protected var _beginstamp:uint;
		protected var _duration:uint;
		protected var _timer:Timer;
		protected var _fadeTimer:Timer;
		protected var _bounds:Rectangle;
		
		public function HighlightAnimation( bounds:Rectangle, bitmapData:BitmapData = null )
		{
			super();
						
			_bounds = bounds;
			_bmp = new Bitmap( bitmapData );
			_bmpHighlight = new Bitmap( bitmapData );
			_highlightMask = new Shape();
			_bmpHighlight.mask = _highlightMask;
			
			_bmpHighlight.alpha = 1;
			
			_highlights = new Array();
			
			_fadeTimer = new Timer( 3000, 1 );
			_fadeTimer.addEventListener( TimerEvent.TIMER_COMPLETE, highlightsComplete );
			
			_timer = new Timer( 50, 0 );
			_timer.addEventListener( TimerEvent.TIMER, nextHighlight );
			_timer.addEventListener( TimerEvent.TIMER_COMPLETE, animationComplete );			
			
			addChild( _bmp );
			addChild( _bmpHighlight );
			addChild( _highlightMask );
		}
		
		public function get running():Boolean
		{
			return _timer.running;
		}
		
		public function get duration():uint
		{
			return _duration;
		}
		
		public function get highlights():Array
		{
			return _highlights;
		}
		
		public function set bitmapData( bmpd:BitmapData ):void
		{
			this._bmp.bitmapData = bmpd;
			this._bmpHighlight.bitmapData = bmpd;
		}
		
		/**
		 *  Op het moment dat de tafel begint met opnemen, initialiseert de highlightanimation 
		 *  Om vingers te capturen die het scherm aanraken. 
		*/
		public function startRecording():void
		{
			_bmp.alpha = 0.4;
			_highlights = new Array();
			_highlightMask.graphics.clear();
			_beginstamp = new Date().getTime();
		}
		
		public function stopRecording():void
		{
			_duration = new Date().getTime() - _beginstamp; 
		}
		
		/**
		 * de addHighlight wordt aangeroepen zodra deze een @param point( een vinger ) binnenkrijgt. Deze verwerken hij in de _highlights array en tekent hem gelijk
		 */
		public function addHighlight( point:Point ):void
		{
			var hl:Highlight = new Highlight( point.x, point.y, new Date().getTime() - _beginstamp );			
			_highlights.push( hl );
			
			drawHighlight( hl );
		}
		
		/**
		 * drawHighlight 
		 * @param	hl
		 */
		protected function drawHighlight( hl:Highlight ):void
		{
			_highlightMask.graphics.beginFill( 0xFFFFFF, 1 );
			_highlightMask.graphics.drawCircle( hl.x - _bounds.x, hl.y - _bounds.y, 70 );
			_highlightMask.graphics.endFill();
		}
		
		public function start():void
		{	
			if( _timer.running )
			{
				reset();
				TweenMax.to( this._bmp, 3, {alpha:1, onComplete:animationComplete} );
			}
			else
			{
				this._highlightMask.graphics.clear();
				_bmp.alpha = 0.4;
				reset();
				
				this._timer.start();
			}
		}
		
		public function reset():void
		{
			_index = 0;
			_timer.stop();
			_timer.reset();
		}
		
		protected function nextHighlight( event:TimerEvent ):void
		{
			var delay:Number = _timer.delay;
			var timestamp:Number = _timer.currentCount * delay;
			var hl:Highlight = _highlights[ _index ];
						
			if( _index < _highlights.length && hl.timestamp < timestamp + delay && hl.timestamp > timestamp - delay )
			{
				drawHighlight( hl );
				
				if( ++_index >= _highlights.length )
				{					
					_fadeTimer.start();
				}
			}
		}
		
		
		protected function highlightsComplete( event:TimerEvent ):void
		{
			_fadeTimer.reset();
			TweenMax.to( this._bmp, 3, {alpha:1} );
		}
		
		protected function animationComplete( event:TimerEvent = null ):void
		{
			dispatchEvent( new AnimationEvent( AnimationEvent.ANIMATION_FINISH ) );
			reset();
		}
	}
}